/**
 * Class Base
 * the class that used form other components for base
 */
Base = (function() {
	/**
	 * Base constructor
	 * @param [context] {Applicaiton|Page}
	 * @constructor
	 */
    function Base(context) {
        this.context = context;
		this.style = new Style();
    }
	/**
	 * Set content view (this.view) from id or htmlelenent or View
	 * @param view {String|View|HTMLElement} content view element
	 */
    Base.prototype.setContentView = function(view){
        if(!view) return;
        if(view instanceof View){
            this.view = view;
        }else{
            this.view = new View(view);
        }
    };
	/**
	 * Set On click listener
	 * @param callback {Function} click listener
	 * @param [data] {*} extra data
	 */
    Base.prototype.setOnClickListener = function(callback, data) {
        var _this = this;
		if(!(callback instanceof Function)) throw "callback is not a Function";
        this.view.bind("click", function(e){
            e.stopPropagation();
            callback.call(_this, e, data);
        });
    };
	/**
	 * Set On touchstart listener
	 * @param callback {Function} touchstart listener
	 * @param [data] {*} extra data
	 */
	Base.prototype.setOnTouchStartListener = function(callback, data) {
		var _this = this;
		if(!(callback instanceof Function)) throw "callback is not a Function";
		this.view.bind("touchstart", function(e){
			e.stopPropagation();
			callback.call(_this, e, data);
		});
	};
	/**
	 * Set On touchmove listener
	 * @param callback {Function} touchmove listener
	 * @param [data] {*} extra data
	 */
	Base.prototype.setOnTouchMoveListener = function(callback, data) {
		var _this = this;
		if(!(callback instanceof Function)) throw "callback is not a Function";
		this.view.bind("touchmove", function(e){
			e.stopPropagation();
			callback.call(_this, e, data);
		});
	};
	/**
	 * Set On touchend listener
	 * @param callback {Function} touchend listener
	 * @param [data] {*} extra data
	 */
	Base.prototype.setOnTouchEndListener = function(callback, data) {
		var _this = this;
		if(!(callback instanceof Function)) throw "callback is not a Function";
		this.view.bind("touchend", function(e){
			e.stopPropagation();
			callback.call(_this, e, data);
		});
	};
	/**
	 * On Show method call when this is showed
	 * @param [intent] {Intent} intent that we show this element
	 */
    Base.prototype.onShow = function(intent) {};
	/**
	 * Before Show method call before this is showed
	 * @param [intent] {Intent} intent that we show this element
	 */
    Base.prototype.beforeShow = function(intent) {};
	/**
	 * On Hide method call when this is hided
	 * @param [intent] {Intent} intent that we hide this element
	 */
    Base.prototype.onHide = function(intent) {
        this.view.removeClass("current");
    };
	/**
	 * Before Hide method call before this is hided
	 * @param [intent] {Intent} intent that we hide this element
	 */
    Base.prototype.beforeHide = function(intent) {};
	/**
	 * Method that show this content view with or without animation
	 * @param [intent] {Intent} intent that we show this element
	 */
    Base.prototype.show = function(intent) {
		this.beforeShow(intent);
		if (this.animation){
			this.setOnAnimationEndListener(function(){
				this.onShow(intent);
			});
			this.startAnimation();
		}else{
            this.onShow(intent);
        }
        this.view.addClass("current");
    };
	/**
	 * Method that hide this content view with or without animation
	 * @param [intent] {Intent} intent that we hide this element
	 */
    Base.prototype.hide = function(intent) {
		this.beforeHide(intent);
		if(this.animation){
			this.setOnAnimationEndListener(function(){
				this.onHide(intent);
			});
			this.startAnimation();
		}else{
            this.onHide(intent);
        }
    };
	/**
	 * @deprecated use setAnimation(name)
	 * @param name
	 */
    Base.prototype.setTranslation = function(name){
		this.setAnimation(name);
    };
	/**
	 * @deprecated user startAnimation()
	 * @param listener
	 */
	Base.prototype.startTranslation = function(listener){
		this.setOnAnimationEndListener(listener);
		this.startAnimation();
	};
	/**
	 * Set On Transition End Listener
	 * @param listener {Function} transition end listener
	 */
	Base.prototype.setOnTransitionEndListener = function(listener){
		var _this = this;
		if(!(listener instanceof Function)) throw "listener is not a Function";
		this.transitionEndCallback = function() {
			if(_this.transitionEndListener) _this.transitionEndListener.call(_this);
		};
		this.transitionEndListener = listener;
		this.view.addEvent("webkitTransitionEnd", this.transitionEndCallback);
	};
	/**
	 * Remove transition end listener
	 */
	Base.prototype.removeOnTransitionEndListener = function(){
		this.transitionEndListener = void 0;
		this.view.removeEvent("webkitTransitionEnd", this.transitionEndCallback);
	};
	/**
	 * Set animation with name or Animation object
	 * @param animation {String|Animation} animation name or animation object
	 */
	Base.prototype.setAnimation = function(animation){
		if(!animation) return;
		if(typeof animation === "string"){
			this.animation = animation;
			return;
		}
		if(!(animation instanceof Animation)) return;
		this.animation = animation.name;
	};
	/**
	 * Set on animation end listener
	 * @param listener {Function} animation end listener
	 */
	Base.prototype.setOnAnimationEndListener = function(listener){
		if(!(listener instanceof Function)) throw "listener is not a Function";
		this.аnimationEndListener = listener;
	};
	/**
	 * Start Animation if we have one
	 */
	Base.prototype.startAnimation = function(){
		var callback,
			_this = this;

		if(!this.animation){
			this.animation = "";
			this.view.removeEvent("webkitAnimationEnd", callback);
			if(this.аnimationEndListener) this.аnimationEndListener.call(this);
			this.аnimationEndListener = void 0;
			return;
		}
		this.view.addEvent("webkitAnimationEnd", callback = function(e) {
			_this.view.removeClass(_this.animation);
			if(_this.аnimationEndListener) _this.аnimationEndListener.call(_this);
			_this.аnimationEndListener = void 0;
			_this.animation = "";
			_this.view.removeEvent("webkitAnimationEnd", callback);
		});

		this.view.addClass(this.animation || "");
	};

    return Base;

})();
